package cn.chinaunicom.sdsi.frm.workflow.task.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import cn.chinaunicom.sdsi.frm.workflow.bean.HistoicFlowVO;
import cn.chinaunicom.sdsi.frm.workflow.common.WorkflowConstants;
import cn.chinaunicom.sdsi.frm.workflow.task.dao.FlowHistoryDao;

/**
 * 工作流流转历史数据访问层控件
 * 
 * @author liyh
 */
@Repository("flowHistoryDao")
public class FlowHistoryDaoImpl implements FlowHistoryDao {

	/**
	 * Spring提供的JDBC工具
	 */
	private JdbcTemplate jdbcTemplate;

	/**
	 * 据流程实例ID查到流转历史
	 * 
	 * @param procInsId
	 *            流程实例ID
	 * @return 流转历史集合
	 */
	@Override
	public List<HistoicFlowVO> findFlowHistory(String procInsId) {

		StringBuilder sb = new StringBuilder("SELECT FL.HISTORY_ID, FL.PROC_INST_ID, FL.TASK_ID, FL.PRE_TASK_ID,");
		sb.append(" FL.LINK_KEY, FL.LINK_NAME, FL.USER_ID, FL.USER_NAME, FL.ORG_ID, FL.ORG_NAME, FL.HANDLE_TYPE,")
				.append(" FL.START_TIME, FL.END_TIME, FL.USER_COMMENT, FL.CAN_WITHDRAW, FL.IS_QUICKBACK")
				.append(" FROM FLOW_HISTORY FL WHERE FL.PROC_INST_ID = ? ORDER BY FL.START_TIME,")
				.append(" CASE WHEN FL.END_TIME IS NULL THEN 2 ELSE 1 END ASC, FL.END_TIME");

		List<Object> params = new ArrayList<Object>();
		params.add(procInsId);
		List<Map<String, Object>> list = jdbcTemplate.queryForList(sb.toString(), params.toArray());

		if (list != null && list.size() > 0) {

			List<HistoicFlowVO> results = new ArrayList<HistoicFlowVO>();
			for (int i = 0; i < list.size(); i++) {
				HistoicFlowVO hfo = new HistoicFlowVO();
				Map<String, Object> map = list.get(i);

				hfo.setId(Integer.parseInt(String.valueOf(map.get("HISTORY_ID"))));
				hfo.setProcessInstanceId(String.valueOf(map.get("PROC_INST_ID")));
				hfo.setTaskId(String.valueOf(map.get("TASK_ID")));
				hfo.setPreTaskId(String.valueOf(map.get("PRE_TASK_ID")));
				hfo.setLinkKey(String.valueOf(map.get("LINK_KEY")));
				hfo.setLinkName(String.valueOf(map.get("LINK_NAME")));
				hfo.setAssigneeId(String.valueOf(map.get("USER_ID")));
				hfo.setAssigneeName(String.valueOf(map.get("USER_NAME")));
				hfo.setOrgId(String.valueOf(map.get("ORG_ID")));
				hfo.setOrgName(String.valueOf(map.get("ORG_NAME")));

				int handleType = Integer.parseInt(String.valueOf(map.get("HANDLE_TYPE")));
				String handleTypeInfo = WorkflowConstants.HANDLE_TYPE_WAIT;
				if (handleType == 1) {
					handleTypeInfo = WorkflowConstants.HANDLE_TYPE_PASS;
				} else if (handleType == 2) {
					handleTypeInfo = WorkflowConstants.HANDLE_TYPE_BACK;
				} else if (handleType == 3) {
					handleTypeInfo = WorkflowConstants.HANDLE_TYPE_BREAK;
				} else if (handleType == 4) {
					handleTypeInfo = WorkflowConstants.HANDLE_TYPE_WITHDRAW;
				} else if (handleType == 5) {
					handleTypeInfo = WorkflowConstants.HANDLE_TYPE_TURN;
				}
				hfo.setHandleType(handleTypeInfo);

				hfo.setStartTime((Date) map.get("START_TIME"));
				hfo.setEndTime((Date) map.get("END_TIME"));

				String userComment = "";
				if (map.get("USER_COMMENT") != null) {
					userComment = String.valueOf(map.get("USER_COMMENT"));
				}
				hfo.setUserComment(userComment);
				int withdraw = Integer.parseInt(String.valueOf(map.get("CAN_WITHDRAW")));
				hfo.setWithdraw(withdraw == 1 ? true : false);
				int quickBack = Integer.parseInt(String.valueOf(map.get("IS_QUICKBACK")));
				hfo.setQuickBack(quickBack == 1 ? true : false);

				results.add(hfo);
			}
			return results;
		}

		return null;
	}

	/**
	 * 根据流程实例ID及历史任务ID获取流转历史记录
	 * 
	 * @param processInstanceId
	 *            实例ID
	 * @param taskId
	 *            任务ID
	 * @return 历史任务实体
	 */
	@Override
	public HistoicFlowVO findFlowHistory(String processInstanceId, String taskId) {
		StringBuilder sb = new StringBuilder("SELECT FL.HISTORY_ID, FL.PROC_INST_ID, FL.TASK_ID, FL.PRE_TASK_ID,");
		sb.append(" FL.LINK_KEY, FL.LINK_NAME, FL.USER_ID, FL.USER_NAME, FL.ORG_ID, FL.ORG_NAME, FL.HANDLE_TYPE,")
				.append(" FL.START_TIME, FL.END_TIME, FL.USER_COMMENT, FL.CAN_WITHDRAW, FL.IS_QUICKBACK FROM FLOW_HISTORY FL")
				.append(" WHERE FL.PROC_INST_ID = ? AND FL.TASK_ID = ?");

		List<Object> params = new ArrayList<Object>();
		params.add(processInstanceId);
		params.add(taskId);
		List<Map<String, Object>> list = jdbcTemplate.queryForList(sb.toString(), params.toArray());

		if (list != null && list.size() > 0) {
			HistoicFlowVO hfo = new HistoicFlowVO();
			Map<String, Object> map = list.get(0);

			hfo.setId(Integer.parseInt(String.valueOf(map.get("HISTORY_ID"))));
			hfo.setProcessInstanceId(String.valueOf(map.get("PROC_INST_ID")));
			hfo.setTaskId(String.valueOf(map.get("TASK_ID")));
			hfo.setPreTaskId(String.valueOf(map.get("PRE_TASK_ID")));
			hfo.setLinkKey(String.valueOf(map.get("LINK_KEY")));
			hfo.setLinkName(String.valueOf(map.get("LINK_NAME")));
			hfo.setAssigneeId(String.valueOf(map.get("USER_ID")));
			hfo.setAssigneeName(String.valueOf(map.get("USER_NAME")));
			hfo.setOrgId(String.valueOf(map.get("ORG_ID")));
			hfo.setOrgName(String.valueOf(map.get("ORG_NAME")));

			int handleType = Integer.parseInt(String.valueOf(map.get("HANDLE_TYPE")));
			String handleTypeInfo = WorkflowConstants.HANDLE_TYPE_WAIT;
			if (handleType == 1) {
				handleTypeInfo = WorkflowConstants.HANDLE_TYPE_PASS;
			} else if (handleType == 2) {
				handleTypeInfo = WorkflowConstants.HANDLE_TYPE_BACK;
			} else if (handleType == 3) {
				handleTypeInfo = WorkflowConstants.HANDLE_TYPE_BREAK;
			} else if (handleType == 4) {
				handleTypeInfo = WorkflowConstants.HANDLE_TYPE_WITHDRAW;
			} else if (handleType == 5) {
				handleTypeInfo = WorkflowConstants.HANDLE_TYPE_TURN;
			}
			hfo.setHandleType(handleTypeInfo);

			hfo.setStartTime((Date) map.get("START_TIME"));
			hfo.setEndTime((Date) map.get("END_TIME"));

			String userComment = "";
			if (map.get("USER_COMMENT") != null) {
				userComment = String.valueOf(map.get("USER_COMMENT"));
			}
			hfo.setUserComment(userComment);
			int withdraw = Integer.parseInt(String.valueOf(map.get("CAN_WITHDRAW")));
			hfo.setWithdraw(withdraw == 1 ? true : false);
			int quickBack = Integer.parseInt(String.valueOf(map.get("IS_QUICKBACK")));
			hfo.setQuickBack(quickBack == 1 ? true : false);

			return hfo;
		}

		return null;
	}

	/**
	 * 插入完整环节流转历史
	 * 
	 * @param hfo
	 *            流转历史信息
	 * @return 插入数据的条数
	 */
	@Override
	public int insertWholeFlowHistory(HistoicFlowVO hfo) {

		StringBuilder sb = new StringBuilder("INSERT INTO FLOW_HISTORY (");
		sb.append(" HISTORY_ID, PROC_INST_ID, TASK_ID, PRE_TASK_ID, LINK_KEY, LINK_NAME, USER_ID, USER_NAME,")
				.append(" ORG_ID, ORG_NAME, HANDLE_TYPE, START_TIME, END_TIME, USER_COMMENT, CAN_WITHDRAW, IS_QUICKBACK)")
				.append(" VALUES ( NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

		List<Object> params = new ArrayList<Object>();
		params.add(hfo.getProcessInstanceId());
		params.add(hfo.getTaskId());
		params.add(hfo.getPreTaskId());
		params.add(hfo.getLinkKey());
		params.add(hfo.getLinkName());
		params.add(hfo.getAssigneeId());
		params.add(hfo.getAssigneeName());
		params.add(hfo.getOrgId());
		params.add(hfo.getOrgName());
		String handleTypeInfo = hfo.getHandleType();
		int handleType = 0;
		if (WorkflowConstants.HANDLE_TYPE_PASS.equals(handleTypeInfo)) {
			handleType = 1;
		} else if (WorkflowConstants.HANDLE_TYPE_BACK.equals(handleTypeInfo)) {
			handleType = 2;
		} else if (WorkflowConstants.HANDLE_TYPE_BREAK.equals(handleTypeInfo)) {
			handleType = 3;
		} else if (WorkflowConstants.HANDLE_TYPE_WITHDRAW.equals(handleTypeInfo)) {
			handleType = 4;
		} else if (WorkflowConstants.HANDLE_TYPE_TURN.equals(handleTypeInfo)) {
			handleType = 5;
		}
		params.add(handleType);
		params.add(hfo.getStartTime());
		params.add(hfo.getEndTime());
		params.add(hfo.getUserComment());
		if (hfo.isWithdraw()) {
			params.add(1);
		} else {
			params.add(0);
		}
		if (hfo.isQuickBack()) {
			params.add(1);
		} else {
			params.add(0);
		}

		return jdbcTemplate.update(sb.toString(), params.toArray());
	}

	/**
	 * 插入新生环节流转历史部分信息，较完整环节流转历史缺少处理方式、结束时间及评论
	 * 
	 * @param hfo
	 *            流转历史信息
	 * @return 插入数据的条数
	 */
	@Override
	public int insertNewFlowHistory(HistoicFlowVO hfo) {

		StringBuilder sb = new StringBuilder("INSERT INTO FLOW_HISTORY ( HISTORY_ID, PROC_INST_ID, TASK_ID,");
		sb.append(" PRE_TASK_ID, LINK_KEY, LINK_NAME, USER_ID, USER_NAME, ORG_ID, ORG_NAME, START_TIME, CAN_WITHDRAW,")
				.append(" IS_QUICKBACK) VALUES ( NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 0)");

		List<Object> params = new ArrayList<Object>();
		params.add(hfo.getProcessInstanceId());
		params.add(hfo.getTaskId());
		params.add(hfo.getPreTaskId());
		params.add(hfo.getLinkKey());
		params.add(hfo.getLinkName());
		params.add(hfo.getAssigneeId());
		params.add(hfo.getAssigneeName());
		params.add(hfo.getOrgId());
		params.add(hfo.getOrgName());
		params.add(hfo.getStartTime());

		return jdbcTemplate.update(sb.toString(), params.toArray());
	}

	/**
	 * 补全当前环节处理信息，包含处理时间、处理类型及评论内容。考虑撤回等问题，还需要更新处理人ID及处理人名称字段
	 * 
	 * @param hfo
	 *            流转历史信息
	 * @return 更新的数据条数
	 */
	@Override
	public int supplementaryFlowHistory(HistoicFlowVO hfo) {

		StringBuilder sb = new StringBuilder("UPDATE FLOW_HISTORY SET HANDLE_TYPE = ?,");
		sb.append(" END_TIME = ?, USER_COMMENT = ?, CAN_WITHDRAW = ?, IS_QUICKBACK = ? WHERE TASK_ID = ?");
		List<Object> params = new ArrayList<Object>();

		String handleTypeInfo = hfo.getHandleType();
		int handleType = 0;
		if (WorkflowConstants.HANDLE_TYPE_PASS.equals(handleTypeInfo)) {
			handleType = 1;
		} else if (WorkflowConstants.HANDLE_TYPE_BACK.equals(handleTypeInfo)) {
			handleType = 2;
		} else if (WorkflowConstants.HANDLE_TYPE_BREAK.equals(handleTypeInfo)) {
			handleType = 3;
		} else if (WorkflowConstants.HANDLE_TYPE_WITHDRAW.equals(handleTypeInfo)) {
			handleType = 4;
		} else if (WorkflowConstants.HANDLE_TYPE_TURN.equals(handleTypeInfo)) {
			handleType = 5;
		}
		params.add(handleType);
		params.add(hfo.getEndTime());
		params.add(hfo.getUserComment());
		if (hfo.isWithdraw()) {
			params.add(1);
		} else {
			params.add(0);
		}
		if (hfo.isQuickBack()) {
			params.add(1);
		} else {
			params.add(0);
		}
		params.add(hfo.getTaskId());

		return jdbcTemplate.update(sb.toString(), params.toArray());
	}

	/**
	 * 针对撤回功能需要额外处理处理人的信息
	 * 
	 * @param hfo
	 *            流转历史信息
	 * @return 更新的数据条数
	 */
	@Override
	public int updateAssigneeForWithdraw(HistoicFlowVO hfo) {

		StringBuilder sb = new StringBuilder("UPDATE FLOW_HISTORY");
		sb.append(" SET USER_ID = ?, USER_NAME = ?, ORG_ID = ?, ORG_NAME = ? WHERE PROC_INST_ID = ? AND TASK_ID = ?");
		List<Object> params = new ArrayList<Object>();

		params.add(hfo.getAssigneeId());
		params.add(hfo.getAssigneeName());
		params.add(hfo.getOrgId());
		params.add(hfo.getOrgName());
		params.add(hfo.getProcessInstanceId());
		params.add(hfo.getTaskId());

		return jdbcTemplate.update(sb.toString(), params.toArray());
	}

	/**
	 * 浏览待办后，为上环节处理人不可撤回打标
	 * 
	 * @param processInstanceId
	 *            实例ID
	 * @param taskId
	 *            任务ID
	 * @return 更新记录数，正常为1
	 */
	@Override
	public int signTask(String processInstanceId, String taskId) {

		StringBuilder sb = new StringBuilder("UPDATE FLOW_HISTORY");
		sb.append(" SET CAN_WITHDRAW = 0 WHERE PROC_INST_ID = ? AND TASK_ID = ?");
		List<Object> params = new ArrayList<Object>();

		params.add(processInstanceId);
		params.add(taskId);

		return jdbcTemplate.update(sb.toString(), params.toArray());
	}

	@Autowired
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

}
